"""
Color output utilities for the CLI.

Provides colored terminal output with fallback for non-color terminals.
"""

import os
import sys
from typing import Optional
from enum import Enum


class Color(Enum):
    """ANSI color codes."""
    # Text colors
    BLACK = '\033[30m'
    RED = '\033[31m'
    GREEN = '\033[32m'
    YELLOW = '\033[33m'
    BLUE = '\033[34m'
    MAGENTA = '\033[35m'
    CYAN = '\033[36m'
    WHITE = '\033[37m'
    
    # Bright colors
    BRIGHT_BLACK = '\033[90m'
    BRIGHT_RED = '\033[91m'
    BRIGHT_GREEN = '\033[92m'
    BRIGHT_YELLOW = '\033[93m'
    BRIGHT_BLUE = '\033[94m'
    BRIGHT_MAGENTA = '\033[95m'
    BRIGHT_CYAN = '\033[96m'
    BRIGHT_WHITE = '\033[97m'
    
    # Styles
    BOLD = '\033[1m'
    DIM = '\033[2m'
    ITALIC = '\033[3m'
    UNDERLINE = '\033[4m'
    BLINK = '\033[5m'
    REVERSE = '\033[7m'
    
    # Reset
    RESET = '\033[0m'


class ColorPrinter:
    """Handles colored output for the CLI."""
    
    def __init__(self, force_color: bool = False):
        self.colors_enabled = self._should_use_colors(force_color)
        self.quiet_mode = False
    
    def _should_use_colors(self, force_color: bool) -> bool:
        """Determine if colors should be used."""
        if force_color:
            return True
        
        # Check if stdout is a TTY
        if not sys.stdout.isatty():
            return False
        
        # Check environment variables
        if os.getenv('NO_COLOR'):
            return False
        
        if os.getenv('FORCE_COLOR'):
            return True
        
        # Check TERM environment variable
        term = os.getenv('TERM', '')
        if term in ['dumb', '']:
            return False
        
        # Default to True for most terminals
        return True
    
    def disable_colors(self):
        """Disable colored output."""
        self.colors_enabled = False
    
    def enable_colors(self):
        """Enable colored output."""
        self.colors_enabled = True
    
    def set_quiet_mode(self, quiet: bool):
        """Set quiet mode (suppress non-error output)."""
        self.quiet_mode = quiet
    
    def colorize(self, text: str, color: Color) -> str:
        """Apply color to text if colors are enabled."""
        if not self.colors_enabled:
            return text
        return f"{color.value}{text}{Color.RESET.value}"
    
    def print_colored(self, text: str, color: Color, end: str = '\n', file=None):
        """Print colored text."""
        if self.quiet_mode and color not in [Color.RED, Color.BRIGHT_RED]:
            return
        
        output_file = file or sys.stdout
        colored_text = self.colorize(text, color)
        print(colored_text, end=end, file=output_file)
    
    def print_success(self, text: str, end: str = '\n'):
        """Print success message in green."""
        self.print_colored(f"✓ {text}", Color.BRIGHT_GREEN, end)
    
    def print_error(self, text: str, end: str = '\n'):
        """Print error message in red."""
        self.print_colored(f"✗ {text}", Color.BRIGHT_RED, end, sys.stderr)
    
    def print_warning(self, text: str, end: str = '\n'):
        """Print warning message in yellow."""
        self.print_colored(f"⚠ {text}", Color.BRIGHT_YELLOW, end)
    
    def print_info(self, text: str, end: str = '\n'):
        """Print info message in blue."""
        self.print_colored(f"ℹ {text}", Color.BRIGHT_BLUE, end)
    
    def print_debug(self, text: str, end: str = '\n'):
        """Print debug message in gray."""
        self.print_colored(f"🐛 {text}", Color.BRIGHT_BLACK, end)
    
    def print_header(self, text: str, level: int = 1):
        """Print header with appropriate styling."""
        if level == 1:
            # Main header
            self.print_colored("=" * len(text), Color.BRIGHT_CYAN)
            self.print_colored(text, Color.BRIGHT_CYAN)
            self.print_colored("=" * len(text), Color.BRIGHT_CYAN)
        elif level == 2:
            # Sub header
            self.print_colored(text, Color.BRIGHT_YELLOW)
            self.print_colored("-" * len(text), Color.BRIGHT_YELLOW)
        else:
            # Minor header
            self.print_colored(text, Color.BRIGHT_WHITE)
    
    def print_separator(self, char: str = "-", length: int = 60):
        """Print a separator line."""
        self.print_colored(char * length, Color.DIM)
    
    def print_progress(self, text: str):
        """Print progress message."""
        self.print_colored(f"⏳ {text}", Color.CYAN)
    
    def print_key_value(self, key: str, value: str, key_color: Color = Color.BRIGHT_WHITE, value_color: Color = Color.WHITE):
        """Print key-value pair with colors."""
        key_colored = self.colorize(key, key_color)
        value_colored = self.colorize(str(value), value_color)
        print(f"{key_colored}: {value_colored}")
    
    def print_list_item(self, text: str, bullet: str = "•", indent: int = 0):
        """Print list item with bullet."""
        prefix = " " * indent + bullet + " "
        self.print_colored(prefix + text, Color.WHITE)
    
    def print_code_block(self, code: str, language: str = None):
        """Print code block with syntax highlighting."""
        if not code.strip():
            return
        
        # Header
        lang_text = f" ({language})" if language else ""
        self.print_colored(f"Code{lang_text}:", Color.BRIGHT_CYAN)
        self.print_separator("─", 40)
        
        # Try to use pygments for syntax highlighting if available
        try:
            from pygments import highlight
            from pygments.lexers import get_lexer_by_name, guess_lexer
            from pygments.formatters import TerminalFormatter
            
            if language:
                lexer = get_lexer_by_name(language)
            else:
                lexer = guess_lexer(code)
            
            formatter = TerminalFormatter()
            highlighted = highlight(code, lexer, formatter)
            print(highlighted.rstrip())
            
        except ImportError:
            # Fallback to plain text with minimal coloring
            lines = code.split('\n')
            for line in lines:
                if line.strip().startswith('#') or line.strip().startswith('//'):
                    # Comments
                    self.print_colored(line, Color.BRIGHT_BLACK)
                elif any(keyword in line for keyword in ['def ', 'class ', 'function ', 'var ', 'let ', 'const ']):
                    # Keywords
                    self.print_colored(line, Color.BRIGHT_BLUE)
                else:
                    # Regular code
                    self.print_colored(line, Color.WHITE)
        
        # Footer
        self.print_separator("─", 40)
    
    def print_table_header(self, headers: list, widths: list):
        """Print table header."""
        header_line = "│".join(f" {h:<{w-2}} " for h, w in zip(headers, widths))
        separator_line = "┼".join("─" * w for w in widths)
        
        self.print_colored(f"┌{separator_line.replace('┼', '┬')}┐", Color.BRIGHT_CYAN)
        self.print_colored(f"│{header_line}│", Color.BRIGHT_CYAN)
        self.print_colored(f"├{separator_line}┤", Color.BRIGHT_CYAN)
    
    def print_table_row(self, values: list, widths: list, alternate: bool = False):
        """Print table row."""
        row_line = "│".join(f" {str(v):<{w-2}} " for v, w in zip(values, widths))
        color = Color.WHITE if not alternate else Color.BRIGHT_BLACK
        self.print_colored(f"│{row_line}│", color)
    
    def print_table_footer(self, widths: list):
        """Print table footer."""
        separator_line = "┼".join("─" * w for w in widths)
        self.print_colored(f"└{separator_line.replace('┼', '┴')}┘", Color.BRIGHT_CYAN)
    
    def print_call_tree_node(self, name: str, level: int, is_last: bool = False, has_children: bool = False):
        """Print a call tree node with proper indentation and tree characters."""
        # Create indentation with tree characters
        if level == 0:
            prefix = ""
        else:
            # Tree drawing characters
            if is_last:
                prefix = "  " * (level - 1) + "└─ "
            else:
                prefix = "  " * (level - 1) + "├─ "
        
        # Different colors based on level
        colors = [Color.BRIGHT_WHITE, Color.BRIGHT_GREEN, Color.BRIGHT_YELLOW, Color.BRIGHT_CYAN]
        color = colors[min(level, len(colors) - 1)]
        
        # Add indicator for children
        suffix = " [+]" if has_children else ""
        
        self.print_colored(f"{prefix}{name}{suffix}", color)
    
    def clear_line(self):
        """Clear current line."""
        if self.colors_enabled:
            print('\r\033[K', end='')
        else:
            print('\r' + ' ' * 80 + '\r', end='')
    
    def move_cursor_up(self, lines: int = 1):
        """Move cursor up n lines."""
        if self.colors_enabled:
            print(f'\033[{lines}A', end='')


# Global color printer instance
_global_printer = None


def get_color_printer() -> ColorPrinter:
    """Get global color printer instance."""
    global _global_printer
    if _global_printer is None:
        _global_printer = ColorPrinter()
    return _global_printer